home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / src / exampleCode / GLX / basics / cmapov.c next >
Encoding:
C/C++ Source or Header  |  1994-08-02  |  19.2 KB  |  638 lines

  1. /*
  2.  * Copyright 1992, 1993, 1994, Silicon Graphics, Inc.
  3.  * All Rights Reserved.
  4.  *
  5.  * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
  6.  * the contents of this file may not be disclosed to third parties, copied or
  7.  * duplicated in any form, in whole or in part, without the prior written
  8.  * permission of Silicon Graphics, Inc.
  9.  *
  10.  * RESTRICTED RIGHTS LEGEND:
  11.  * Use, duplication or disclosure by the Government is subject to restrictions
  12.  * as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
  13.  * and Computer Software clause at DFARS 252.227-7013, and/or in similar or
  14.  * successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
  15.  * rights reserved under the Copyright Laws of the United States.
  16.  */
  17. /** header ******************************************************************/
  18.  
  19. /*
  20.  * $Source$
  21.  * $Revision$
  22.  * $Date$
  23.  * $Author$
  24.  *
  25.  * creator: Brett Bainter
  26.  *
  27.  * purpose:
  28.  *    mixed model program demonstrating
  29.  *    ...using custom colormaps for the normal and overlay buffers.
  30.  *    ...moving things with the mouse.
  31.  *
  32.  * compiling:
  33.  *    cc -float -prototypes -O cmapov.c -o cmapov \
  34.  *    -s -lXirisw -lXm_s -lXt_s -lgl_s -lX11_s -lm -lc_s -lPW
  35.  *
  36.  * operating:
  37.  *    Use the left mouse button to move the red, green, and blue blocks.
  38.  *    Verify that they "pass under" the yellow, magenta, and cyan blocks
  39.  *    which are in the overlay planes.
  40.  *
  41.  */
  42.  
  43. /** notes *******************************************************************/
  44.  
  45. /*
  46.  * bugs:
  47.  *    There is a known bug with 8 bit PI's that will cause this program to
  48.  *    run in false colors.  It will initially come up correctly but when
  49.  *    the cursor moves to a gl window (for example, showmap), the colormap
  50.  *    will not be reloaded when the cursor returns to the cmapov window.
  51.  */
  52.  
  53. /** includes ****************************************************************/
  54.  
  55. #include <stdio.h>            /* standard */
  56. #include <Xm/Xm.h>            /* for motif */
  57. #include <Xm/Form.h>            /* motif widget */
  58. #include <Xm/Frame.h>            /* motif widget */
  59. #include <Xm/PushB.h>            /* motif widget */
  60. #include <Xm/RowColumn.h>        /* motif widget */
  61. #include <Xm/Separator.h>        /* motif widget */
  62. #include <X11/Xirisw/GlxMDraw.h>    /* gl widget */
  63.  
  64. /** defines *****************************************************************/
  65.  
  66. /* c environment */
  67. #define global
  68.  
  69. /** typedefs ****************************************************************/
  70. /** prototypes **************************************************************/
  71.  
  72. extern void main(int argc, char *argv[], char *envp[]);
  73.  
  74. /* setup */
  75. static void  install_colormaps(Widget top_level, Widget glw);
  76. static void  normal_cmap_init(Widget glw);
  77. static Pixel normal_cmap_set(Widget glw, int index, short r, short g, short b);
  78. static void  overlay_cmap_init(Widget glw);
  79. static Pixel overlay_cmap_set(Widget glw, int index, short r, short g, short b);
  80.  
  81. /* mixed model support */
  82. static void cb_gl_expose(Widget w, XtPointer client_data, XtPointer call_data);
  83. static void cb_gl_resize(Widget w, XtPointer client_data, XtPointer call_data);
  84. static void cb_gl_ginit(Widget w, XtPointer client_data, XtPointer call_data);
  85. static void cb_gl_input(Widget w, XtPointer client_data, XtPointer call_data);
  86. static void cb_gl_overlay_expose(
  87.     Widget w, XtPointer client_data, XtPointer call_data
  88. );
  89.  
  90. /* callbacks (misc) */
  91. static void cb_quit(Widget w, XtPointer client_data, XtPointer call_data);
  92.  
  93. /* drawing */
  94. static void draw_normal_frame(void);
  95. static void draw_overlay_frame(void);
  96. static void draw_boxes(int c1, int c2, int c3);
  97.  
  98. /** variables ***************************************************************/
  99.  
  100. /* mixed-model configuration */
  101. static GLXconfig glx_config[] = {
  102.     {GLX_NORMAL, GLX_DOUBLE, TRUE},
  103.     {GLX_OVERLAY, GLX_BUFSIZE, 2},
  104.     { 0, 0, 0 },
  105. };
  106.  
  107. /* information which allows us to use the overlay or popup buffer */
  108. static struct {
  109.     char *use;
  110.     char *expose_cb;
  111.     char *window;
  112.     char *visual;
  113.     char *colormap;
  114. } *over_res, over_res_map[2] = {
  115.     /* describe needed overlay resources */
  116.     {   GlxNuseOverlay, GlxNoverlayExposeCallback, GlxNoverlayWindow,
  117.     GlxNoverlayVisual, GlxNoverlayColormap
  118.     },
  119.     /* describe analogous popup resources for when overlays aren't there */
  120.     {   GlxNusePopup, GlxNpopupExposeCallback, GlxNpopupWindow,
  121.     GlxNpopupVisual, GlxNpopupColormap
  122.     },
  123. };
  124.  
  125. /* normal buffer colors */
  126. static Pixel n_grey, n_red, n_green, n_blue;
  127.  
  128. /* overlay buffer colors */
  129. static Pixel o_trans, o_yellow, o_magenta, o_cyan;
  130.  
  131. /* gl window info */
  132. static struct {
  133.     Dimension width;        /* in pixels */
  134.     Dimension height;        /* in pixels */
  135.     float pt[3];        /* world position of moving object */
  136. } glwin = {400, 400, {15.0, 20.0, 0.0}};
  137.  
  138. /** functions ***************************************************************/
  139.  
  140. /*
  141.  * main - program entry point.
  142.  */
  143. global void main(
  144.     int argc,            /* argument count */
  145.     char *argv[],        /* argument vector */
  146.     char *envp[]        /* environment pointer */
  147. )
  148. {
  149.     XtAppContext app_context;    /* application context */
  150.     Widget app_shell;        /* first widget */
  151.     Widget form;        /* surrounds app */
  152.     Widget rowcol;        /* manages input buttons */
  153.     Widget button;        /* quit button */
  154.     Widget separator;        /* between input and output */
  155.     Widget frame;        /* to surround gl widget */
  156.     Widget glw;            /* the gl widget inside window */
  157.     Arg args[15];        /* for name/value pairs */
  158.     int n;            /* for reusable indices */
  159.  
  160.     /* perform capabilities check */
  161.     /* use popup planes if there is not enough overlay planes */
  162.     over_res = &over_res_map[0];
  163.     if (getgdesc(GD_BITS_OVER_SNG_CMODE) < 2) {
  164.     glx_config[1].buffer = GLX_POPUP;
  165.     over_res = &over_res_map[1];
  166.     }
  167.     printf("\nUsing the %s planes\n",
  168.     over_res==over_res_map? "OVERLAY" : "POPUP"
  169.     );
  170.  
  171.     /* initialize toolkit, creating application shell */
  172.     n = 0;
  173.     XtSetArg(args[n], XmNtitle, "CMode Overlay"); n++;
  174.     app_shell = XtAppInitialize(
  175.     &app_context, "Cmapov", NULL, 0, &argc, argv, NULL, args, n
  176.     );
  177.  
  178.     /* create container for app */
  179.     n = 0;
  180.     form = XmCreateForm(app_shell, "form", args, n);
  181.     XtManageChild(form);
  182.  
  183.     /* create the command area */
  184.     n = 0;
  185.     XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++;
  186.     XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); n++;
  187.     XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++;
  188.     XtSetArg(args[n], XmNorientation, XmVERTICAL); n++;
  189.     rowcol = XmCreateRowColumn(form, "rowcol", args, n);
  190.     XtManageChild(rowcol);
  191.  
  192.     /* create the command area buttons */
  193.     n = 0;
  194.     button = XmCreatePushButton(rowcol, "Quit", args, n);
  195.     XtAddCallback(button, XmNactivateCallback, cb_quit, NULL);
  196.     XtManageChild(button);
  197.  
  198.     /* create separator between command area and output area */
  199.     n = 0;
  200.     XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); n++;
  201.     XtSetArg(args[n], XmNleftWidget, rowcol); n++;
  202.     XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); n++;
  203.     XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++;
  204.     XtSetArg(args[n], XmNorientation, XmVERTICAL); n++;
  205.     separator = XmCreateSeparator(form, "separator", args, n);
  206.     XtManageChild(separator);
  207.  
  208.     /* create the output area */
  209.     /* create the frame */
  210.     n = 0;
  211.     XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); n++;
  212.     XtSetArg(args[n], XmNleftWidget, separator); n++;
  213.     XtSetArg(args[n], XmNleftOffset, 5); n++;
  214.     XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++;
  215.     XtSetArg(args[n], XmNrightOffset, 5); n++;
  216.     XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); n++;
  217.     XtSetArg(args[n], XmNbottomOffset, 5); n++;
  218.     XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++;
  219.     XtSetArg(args[n], XmNtopOffset, 5); n++;
  220.     XtSetArg(args[n], XmNshadowThickness, 6); n++;
  221.     frame = XmCreateFrame(form, "frame", args, n);
  222.     XtManageChild(frame);
  223.  
  224.     /* create the gl widget */
  225.     n = 0;
  226.     XtSetArg(args[n], GlxNglxConfig, glx_config); n++;
  227.     XtSetArg(args[n], over_res->use, True); n++;
  228.     XtSetArg(args[n], XmNborderWidth, 0); n++;
  229.     XtSetArg(args[n], XmNwidth, glwin.width); n++;
  230.     XtSetArg(args[n], XmNheight, glwin.height); n++;
  231.     glw = GlxCreateMDraw(frame, "glw", args, n);
  232.     XtManageChild(glw);
  233.     XtAddCallback(glw, GlxNexposeCallback, cb_gl_expose, 0);
  234.     XtAddCallback(glw, GlxNresizeCallback, cb_gl_resize, 0);
  235.     XtAddCallback(glw, GlxNginitCallback, cb_gl_ginit, 0);
  236.     XtAddCallback(glw, GlxNinputCallback, cb_gl_input, 0);
  237.     XtAddCallback(glw, over_res->expose_cb, cb_gl_overlay_expose, 0);
  238.  
  239.     /* setup custom normal colormap */
  240.     normal_cmap_init(glw);
  241.     n_grey  = normal_cmap_set(glw, 0, 125, 125, 125);
  242.     n_red   = normal_cmap_set(glw, 1, 255,   0,   0);
  243.     n_green = normal_cmap_set(glw, 2,   0, 255,   0);
  244.     n_blue  = normal_cmap_set(glw, 3,   0,   0, 255);
  245.  
  246.     /* setup custom overlay colormap */
  247.     overlay_cmap_init(glw);
  248.     o_trans   = 0;    /* transparent is always zero */
  249.     o_yellow  = overlay_cmap_set(glw, 0, 255, 255,   0);
  250.     o_magenta = overlay_cmap_set(glw, 1, 255,   0, 255);
  251.     o_cyan    = overlay_cmap_set(glw, 2,   0, 255, 255);
  252.  
  253.     /* realize the app, creating the actual x windows */
  254.     XtRealizeWidget(app_shell);
  255.  
  256.     /* setup for colormap installation */
  257.     install_colormaps(app_shell, glw);
  258.  
  259.     /* enter the event loop */
  260.     XtAppMainLoop(app_context);
  261. }
  262.  
  263.  
  264. /*- support: setup ---------------------------------------------------------*/
  265. /*
  266.  * install_colormaps - let the window manager know about our colormaps.
  267.  *
  268.  * This has been generalized to handle any windows a gl widget might have.
  269.  * It may not necessarily being using any of them.
  270.  */
  271. static void install_colormaps(Widget top_level, Widget glw)
  272. {
  273.     Window overlay_win, popup_win, underlay_win;
  274.     Window window[5];
  275.     int i;
  276.  
  277.     XtVaGetValues(
  278.     glw,
  279.     GlxNoverlayWindow, &overlay_win,
  280.     GlxNpopupWindow, &popup_win,
  281.     GlxNunderlayWindow, &underlay_win,
  282.     NULL
  283.     );
  284.     i = 0;
  285.     if (overlay_win)
  286.     window[i++] = overlay_win;
  287.     if (popup_win)
  288.     window[i++] = popup_win;
  289.     if (underlay_win)
  290.     window[i++] = underlay_win;
  291.     window[i++] = XtWindow(glw);
  292.     window[i++] = XtWindow(top_level);
  293.     XSetWMColormapWindows(XtDisplay(top_level), XtWindow(top_level), window, i);
  294. }
  295.  
  296.  
  297. /*- support: custom normal colormap ----------------------------------------*/
  298. /*
  299.  * normal_cmap_init - create a new normal colormap for the gl widget.
  300.  *
  301.  * The gl widget must already be created prior to calling this function,
  302.  * however the gl widget does not need to be realized for it to work.  This
  303.  * is because the window it uses in creating the colormap is the root window
  304.  * on the same screen.
  305.  */
  306. static void normal_cmap_init(Widget glw)
  307. {
  308.     Display *display;
  309.     Window window;
  310.     XVisualInfo *visinfo;
  311.     Colormap pmap;
  312.     Colormap cmap;
  313.     XColor *color;
  314.     int ncolors;
  315.     int i;
  316.  
  317.     /* get display; any window on the same screen; and the visual */
  318.     display = XtDisplay(glw);
  319.     window = RootWindowOfScreen(XtScreen(glw));
  320.     XtVaGetValues(glw, XmNvisual, &visinfo, NULL);
  321.  
  322.     /* create new normal colormap, allocating all entries */
  323.     cmap = XCreateColormap(display, window, visinfo->visual, AllocAll);
  324.  
  325.     /* set new normal colormap for the gl widget */
  326.     XtVaSetValues(glw, XmNcolormap, cmap, NULL);
  327.  
  328.     /*
  329.      * duplicate the parent's default colors for the lower colormap entries
  330.      * (max 256) to avoid colormap flashing on machines with only one h/w
  331.      * colormap.
  332.      */
  333.     XtVaGetValues(XtParent(glw), XmNcolormap, &pmap, NULL);
  334.     ncolors = visinfo->colormap_size;
  335.     printf("\nnormal colors = %d\n", ncolors);
  336.     if (ncolors > 256)
  337.     ncolors = 256;
  338.     color = (XColor *) XtMalloc(ncolors*sizeof(XColor));
  339.     for (i=0; i<ncolors; i++)
  340.     color[i].pixel = i;
  341.     XQueryColors(display, pmap, color, ncolors);
  342.     XStoreColors(display, cmap, color, ncolors);
  343.     XtFree(color);
  344. }
  345.  
  346.  
  347. /*
  348.  * normal_cmap_set - map a color for the normal buffer.
  349.  *
  350.  * This uses a simple scheme of mapping the colors backwards from the highest
  351.  * colormap index.
  352.  */
  353. static Pixel normal_cmap_set(Widget glw, int index, short r, short g, short b)
  354. {
  355.     XVisualInfo *visinfo;
  356.     Colormap cmap;
  357.     XColor color;
  358.     int n_last;
  359.  
  360.     XtVaGetValues(glw, XmNvisual, &visinfo, XmNcolormap, &cmap, NULL);
  361.     n_last = visinfo->colormap_size-1;
  362.     color.pixel = n_last - index; /* work backwards from the last position */
  363.     color.flags = DoRed | DoGreen | DoBlue;
  364.     color.red   = r << 8;
  365.     color.green = g << 8;
  366.     color.blue  = b << 8;
  367.     XStoreColor(XtDisplay(glw), cmap, &color);
  368.     return (color.pixel);
  369. }
  370.  
  371.  
  372. /*- support: custom overlay colormap ---------------------------------------*/
  373. /*
  374.  * overlay_cmap_init - create a new overlay colormap for the gl widget.
  375.  *
  376.  * The gl widget must already be created prior to calling this function,
  377.  * however the gl widget does not need to be realized for it to work.  This
  378.  * is because the window it uses in creating the colormap is the root window
  379.  * on the same screen.
  380.  */
  381. static void overlay_cmap_init(Widget glw)
  382. {
  383.     Display *display;
  384.     Window window;
  385.     XVisualInfo *visinfo;
  386.     Colormap cmap;
  387.     XColor color;
  388.     int ncolors;
  389.     Pixel *pixel;
  390.     unsigned long plane_mask[1];
  391.     int result;
  392.  
  393.     /* get display; any window on the same screen; and the visual */
  394.     display = XtDisplay(glw);
  395.     window = RootWindowOfScreen(XtScreen(glw));
  396.     XtVaGetValues(glw, over_res->visual, &visinfo, NULL);
  397.  
  398.     /*
  399.      * create new overlay colormap, allocating no entries.
  400.      * (AllocAll would fail here because index 0 is reserved for transparency)
  401.      */
  402.     cmap = XCreateColormap(display, window, visinfo->visual, AllocNone);
  403.  
  404.     /* set new overlay colormap for the gl widget */
  405.     XtVaSetValues(glw, over_res->colormap, cmap, NULL);
  406.  
  407.     /* allocate every color except transparency as read/write */
  408.     ncolors = visinfo->colormap_size;    /* including transparent color */
  409.     printf("\noverlay colors = %d\n", ncolors);
  410.     pixel = (Pixel *) XtMalloc(ncolors*sizeof(Pixel));    /* stub array */
  411.     result = XAllocColorCells(
  412.     display, cmap, True, plane_mask, 0,
  413.     &pixel[1], ncolors-1    /* one less due to transparency */
  414.     );
  415.     XtFree((char *) pixel);
  416.  
  417.     /* check for booboo */
  418.     if (result == 0)
  419.     fprintf(stderr, "XAllocColorCells failed for overlay buffer.\n");
  420. }
  421.  
  422.  
  423. /*
  424.  * overlay_cmap_set - map a color for the normal buffer.
  425.  *
  426.  * This uses a simple scheme of mapping the colors backwards from the highest
  427.  * colormap index.
  428.  */
  429. static Pixel overlay_cmap_set(Widget glw, int index, short r, short g, short b)
  430. {
  431.     XVisualInfo *visinfo;
  432.     Colormap cmap;
  433.     XColor color;
  434.     int n_last;
  435.  
  436.     XtVaGetValues(
  437.     glw, over_res->visual, &visinfo, over_res->colormap, &cmap, NULL
  438.     );
  439.     n_last = visinfo->colormap_size-1;
  440.     color.pixel = n_last - index; /* work backwards from the last position */
  441.     color.flags = DoRed | DoGreen | DoBlue;
  442.     color.red   = r << 8;
  443.     color.green = g << 8;
  444.     color.blue  = b << 8;
  445.     XStoreColor(XtDisplay(glw), cmap, &color);
  446.     return (color.pixel);
  447. }
  448.  
  449.  
  450. /*- support: callbacks (gl widget) -----------------------------------------*/
  451. /*
  452.  * cb_gl_expose - handle expose events for the gl widget.
  453.  */
  454. static void cb_gl_expose(Widget w, XtPointer client_data, XtPointer call_data)
  455. {
  456.     GlxDrawCallbackStruct *glx = (GlxDrawCallbackStruct *) call_data;
  457.  
  458.     GLXwinset(XtDisplay(w), XtWindow(w));
  459.     draw_normal_frame();
  460. }
  461.  
  462.  
  463. /*
  464.  * cb_gl_resize - handle resize events for the gl widget.
  465.  */
  466. static void cb_gl_resize(Widget w, XtPointer client_data, XtPointer call_data)
  467. {
  468.     GlxDrawCallbackStruct *glx = (GlxDrawCallbackStruct *) call_data;
  469.     Window overlay_window;
  470.  
  471.     /* squirrel away size */
  472.     glwin.width = glx->width;
  473.     glwin.height = glx->height;
  474.  
  475.     /* setup normal buffer viewport */
  476.     GLXwinset(XtDisplay(w), XtWindow(w));
  477.     viewport(0, glx->width-1, 0, glx->height-1);
  478.  
  479.     /* setup overlay buffer viewport */
  480.     XtVaGetValues(w, over_res->window, &overlay_window, NULL);
  481.     GLXwinset(XtDisplay(w), overlay_window);
  482.     viewport(0, glx->width-1, 0, glx->height-1);
  483. }
  484.  
  485.  
  486. /*
  487.  * cb_gl_ginit - perform any necessary graphics initialization.
  488.  */
  489. static void cb_gl_ginit(Widget w, XtPointer client_data, XtPointer call_data)
  490. {
  491.     GlxDrawCallbackStruct *glx = (GlxDrawCallbackStruct *) call_data;
  492.  
  493.     GLXwinset(XtDisplay(w), XtWindow(w));
  494.     mmode(MVIEWING);
  495.     ortho2(-0.5, 100.5, -0.5, 100.5);
  496.     gflush();
  497. }
  498.  
  499.  
  500. /*
  501.  * cb_gl_input - handle input for the gl window.
  502.  */
  503. static void cb_gl_input(Widget w, XtPointer client_data, XtPointer call_data)
  504. {
  505.     static Boolean active = False;    /* currently moving? */
  506.     static float dx, dy;        /* offset from current position */
  507.     /**/
  508.     GlxDrawCallbackStruct *glx = (GlxDrawCallbackStruct *) call_data;
  509.     XEvent *event = glx->event;    /* what occured */
  510.     int msx, msy;        /* gl window mouse position */
  511.     float mwx, mwy;        /* gl world  mouse position */
  512.  
  513.     GLXwinset(XtDisplay(w), XtWindow(w));
  514.  
  515.     /* map to gl window coords */
  516.     msx = event->xbutton.x;            /* same x */
  517.     msy = (glwin.height-1) - event->xbutton.y;    /* flip y */
  518.  
  519.     /* map to gl world coords */
  520.     mwx = 0.0 + ((msx - 0) / (float)glwin.width ) * 100.0;
  521.     mwy = 0.0 + ((msy - 0) / (float)glwin.height) * 100.0;
  522.  
  523.     /* process event */
  524.     switch (event->type) {
  525.     case ButtonPress:
  526.     if (event->xbutton.button == Button1) {
  527.         /* compute delta from current position */
  528.         dx = mwx - glwin.pt[0];
  529.         dy = mwy - glwin.pt[1];
  530.         active = True;
  531.     }
  532.     break;
  533.     case MotionNotify:
  534.     if (active) {
  535.         /* compute new position and draw */
  536.         glwin.pt[0] = mwx - dx;
  537.         glwin.pt[1] = mwy - dy;
  538.         draw_normal_frame();
  539.     }
  540.     break;
  541.     case ButtonRelease:
  542.     if (event->xbutton.button == Button1) {
  543.         /* we're done */
  544.         active = False;
  545.     }
  546.     break;
  547.     }
  548. }
  549.  
  550.  
  551. /*
  552.  * cb_gl_overlay_expose - handle overlay expose events for the gl widget.
  553.  */
  554. static void cb_gl_overlay_expose(
  555.     Widget w, XtPointer client_data, XtPointer call_data
  556. )
  557. {
  558.     GlxDrawCallbackStruct *glx = (GlxDrawCallbackStruct *) call_data;
  559.  
  560.     GLXwinset(XtDisplay(w), glx->window);
  561.     draw_overlay_frame();
  562. }
  563.  
  564.  
  565. /*- support: callbacks (misc) ----------------------------------------------*/
  566. /*
  567.  * cb_quit - exit application.
  568.  */
  569. static void cb_quit(Widget w, XtPointer client_data, XtPointer call_data)
  570. {
  571.     exit(0);
  572. }
  573.  
  574.  
  575. /*- support: drawing -------------------------------------------------------*/
  576. /* 
  577.  * draw_normal_frame - render objects in the normal buffer and swap.
  578.  */
  579. static void draw_normal_frame(void)
  580. {
  581.     color(n_grey);
  582.     clear();
  583.     pushmatrix();
  584.     translate(glwin.pt[0], glwin.pt[1], glwin.pt[2]);
  585.     draw_boxes(n_red, n_green, n_blue);
  586.     popmatrix();
  587.     swapbuffers();
  588.     gflush();
  589. }
  590.  
  591.  
  592. /* 
  593.  * draw_overlay_frame - render objects in the overlay buffer.
  594.  */
  595. static void draw_overlay_frame(void)
  596. {
  597.     color(o_trans);
  598.     clear();
  599.     pushmatrix();
  600.     translate(15.0, 60.0, 0.0);
  601.     draw_boxes(o_yellow, o_cyan, o_magenta);
  602.     popmatrix();
  603.     gflush();
  604. }
  605.  
  606.  
  607. /*
  608.  * draw_boxes - draw three boxes in three different colors.
  609.  */
  610. static void draw_boxes(int c1, int c2, int c3)
  611. {
  612.     static float vert[][2] = {    /* a box */
  613.     { 0.0,  0.0},
  614.     {20.0,  0.0},
  615.     {20.0, 20.0},
  616.     { 0.0, 20.0},
  617.     };
  618.  
  619.     pushmatrix();
  620.     color(c1);
  621.     bgnpolygon();
  622.     v2f(vert[0]); v2f(vert[1]); v2f(vert[2]); v2f(vert[3]);
  623.     endpolygon();
  624.     translate(25.0, 0.0, 0.0);
  625.     color(c2);
  626.     bgnpolygon();
  627.     v2f(vert[0]); v2f(vert[1]); v2f(vert[2]); v2f(vert[3]);
  628.     endpolygon();
  629.     translate(25.0, 0.0, 0.0);
  630.     color(c3);
  631.     bgnpolygon();
  632.     v2f(vert[0]); v2f(vert[1]); v2f(vert[2]); v2f(vert[3]);
  633.     endpolygon();
  634.     popmatrix();
  635. }
  636.  
  637. /** eof *********************************************************************/
  638.